package cn.software.service.impl;

import cn.software.entity.UserClass;
import cn.software.entity.param.UserClassParam;
import cn.software.entity.vo.studentVo;
import cn.software.entity.vo.teacherVo;
import cn.software.ex.PasswordNotMatchException;
import cn.software.ex.UserNotFoundException;
import cn.software.mapper.UserClassMapper;
import cn.software.service.UserService;
import cn.software.ex.InsertException;
import cn.software.ex.UsernameDuplicateException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.software.entity.User;
import cn.software.mapper.UserMapper;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
* @author 眉眼如初
* @description 针对表【user(用户)】的数据库操作Service实现
* @createDate 2023-05-31 20:54:23
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserClassMapper userClassMapper;

    @Override
    public void register(User user) {

        //检查用户名是否被注册
        String username = user.getUsername();
        User result = userMapper.findByUsername(username);
        if(result!=null) {
            throw new UsernameDuplicateException("用户名已被注册");
        }

        //MD5加密算法：盐值+密码+盐值
        String salt = UUID.randomUUID().toString().toUpperCase();
        String  md5Password =getMD5Password(user.getPassword(),salt);
        user.setPassword(md5Password);
        user.setSalt(salt);

        user.setIsDeleted(0);

        Integer rows = userMapper.insert(user);
        if(rows!=1) {
            throw new InsertException("用户注册出错");
        }
    }

    @Override
    public User login(String username, String password) {
        User result = userMapper.findByUsername(username);
        if(result==null) {
            throw new UserNotFoundException("该用户不存在");
        }
        if(result.getIsDeleted()==1) {
            throw new UserNotFoundException("该用户不存在");
        }

        String salt = result.getSalt();
        String oldPassword = result.getPassword();
        String MD5Password = getMD5Password(oldPassword,salt);
        if(!MD5Password.equals(oldPassword)) {
            throw new PasswordNotMatchException("用户密码错误");
        }

        User user = new User();
        user.setId(result.getId());
        user.setName(result.getName());
        user.setUsername(result.getUsername());
        user.setTelNumber(result.getTelNumber());
        user.setGender(result.getGender());
        user.setRoleId(result.getRoleId());

        return user;
    }

    private String getMD5Password(String password , String salt) {
        //使用UUID作为盐值，在原始密码的左右两侧拼接
        for(int i=0 ; i< 3 ; i++ ) {
            password = DigestUtils.md5DigestAsHex((salt+password+salt).getBytes()).toUpperCase();

        }
        return password;
    }

    @Override
    public List<teacherVo> SelectTeacher() {
        QueryWrapper<User> qw =new QueryWrapper<>();
        qw.eq("is_deleted",0);
        qw.eq("role_id",1);
        List<teacherVo> teacherVoList = new ArrayList<>();
        List<User> teacherUSer =  userMapper.selectList(qw);
        for(int i = 0 ; i<teacherUSer.size() ; i++) {
            teacherVo teacherVo = new teacherVo();
            BeanUtils.copyProperties(teacherUSer.get(i),teacherVo);
            teacherVoList.add(teacherVo);
        }
        if(teacherVoList == null) {
            throw new UserNotFoundException("无该用户存在");
        }
        return teacherVoList;
    }

    @Override
    public List<studentVo> selectStudent() {
       QueryWrapper<User> qw = new QueryWrapper<>();
       qw.eq("is_deleted",0);
       qw.eq("role_id",2);
       List<studentVo> studentVoList=new ArrayList<>();
       List<User> studentUser = userMapper.selectList(qw);
       for(int i=0 ; i<studentUser.size() ; i++) {
           studentVo studentVo = new studentVo();
           BeanUtils.copyProperties(studentUser.get(i),studentVo);
           studentVoList.add(studentVo);
       }
       if(studentVoList == null) {
           throw new UserNotFoundException("无该用户存在");
       }
       return studentVoList;
    }

    @Override
    public boolean enterClass(UserClassParam userClassParam) {
        UserClass userClass= new UserClass();
        BeanUtils.copyProperties(userClassParam,userClass);
        int insert=userClassMapper.insert(userClass);
        return insert>0;
    }

    @Override
    public boolean updateUser(User user) {
        String username = user.getUsername();
        User result = userMapper.findByUsername(username);

        String salt = result.getSalt();
        user.setSalt(salt);
        String password = getMD5Password(user.getPassword(),salt);
        user.setPassword(password);
         userMapper.updateById(user);
         return true;

    }

    // 生成Token
    private static String createToken(User user) {
        // 配置JWT
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        byte[] signingKey = "somesecret".getBytes();

        // 设置5分钟过期时间
        long nowMillis = System.currentTimeMillis();
        Date expireDate = new Date(nowMillis + 300000);

        JwtBuilder builder = Jwts.builder()
                .setId(UUID.randomUUID().toString())
                .setIssuedAt(new Date())
                .setSubject("Login Token")
                .claim("user", user)
                .setExpiration(expireDate)
                .signWith(signatureAlgorithm, signingKey);  // 签名

        return builder.compact();
    }

    // 解析Token，返回其中的用户信息
    private static User getUserFromToken(String token) {
        try{
            Claims claims = Jwts.parser()
                    .setSigningKey("somesecret".getBytes())
                    .parseClaimsJws(token).getBody();

            User user = claims.get("user", User.class);
            return user;

        } catch (Exception ex) {
            // Token无效
            return null;
        }
    }



}




